/*!
 * \file nuExecMgr.h
 * \brief Execute object manager.
 * \author Nus
 * \date 2008/02/17, 01:26
 */

#ifndef __NUEXECMGR_H__
#define __NUEXECMGR_H__

#include "Singleton.h"
#include "nuExecute.h"

#define DEFAULT_NUM_OF_PRIORITY 32

/*!
 * \class nuExecMgr
 * \brief Execution manager.
 */
class nuExecMgr : public Singleton< nuExecMgr >
{
  DEFINE_SINGLETON(nuExecMgr);

public:
  //! \brief Initialize with attribute.
  static void initialize(u32 num_pri) {
    if(!mpInstance)
      mpInstance = new nuExecMgr(num_pri);
  }

  //! \brief Get number of priority.
  u32 getNumOfPriority(void) const {
    return mNumPriority;
  }
  
  //! \brief Get number of execute object.
  u32 getNumOfObj(u32 pri) const {
    if(!mpNumOfExecObj || pri >= mNumPriority)
      return 0;
    return mpNumOfExecObj[pri];
  }

  //! \brief Add execute object.
  s32 addExecObj(nuExecute* p_obj, u32 priority);

  //! \brief Remove execute object.
  s32 removeExecObj(nuExecute* p_obj);
  
  //! \brief Get execute object.
  nuExecute* getExecObj(u32 pri) {
    if(mpExecute && pri < mNumPriority)
      return mpExecute[pri];
    return NULL;
  }

  //! \brief Get next execute object.
  nuExecute* getNextExecObj(const nuExecute* obj) {
    if(mpExecute && obj)
      return obj->mpNext;
    return NULL;
  }

  //! \brief Get previous execute object.
  nuExecute* getPrevExecObj(const nuExecute* obj) {
    if(mpExecute && obj)
      return obj->mpPrev;
    return NULL;
  }

protected:
  // None...

private:
  nuExecute** mpExecute;          //!< Execution chain.
  nuExecute** mpLast;             //!< Last object in chain.
  u32* mpNumOfExecObj;            //!< Number of execute object.
  u32 mNumPriority;               //!< Number of priority.

  //! \brief Default constructor.
  nuExecMgr(u32 num_pri = DEFAULT_NUM_OF_PRIORITY);
  
  //! \brief Default destructor.
  ~nuExecMgr();

};

#endif
